Add a way to release GL resources
authorMatthias Clasen <mclasen@redhat.com>
Thu, 18 Jan 2018 01:15:45 +0000 (20:15 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Thu, 18 Jan 2018 01:15:45 +0000 (20:15 -0500)
The inspector may hold on to render nodes and textures
beyond the lifetime of the widget (and thus the GL
resources). To handle this situation, allow the widget
to explicitly release the GL resources, and make
the texture available on the clent-side as a cairo
surface. This lets the recorder still show the content
after the widget is gone.

gdk/gdktexture.c
gdk/gdktexture.h

index c87ed57a1d1d3974c1c4b63f598f05bb23cecaf5..f85b096ec0cb74ec231a3ab98e873965d1216e5b 100644 (file)
@@ -443,6 +443,8 @@ struct _GdkGLTexture {
   GdkGLContext *context;
   int id;
 
+  cairo_surface_t *saved;
+
   GDestroyNotify destroy;
   gpointer data;
 };
@@ -458,10 +460,21 @@ gdk_gl_texture_dispose (GObject *object)
 {
   GdkGLTexture *self = GDK_GL_TEXTURE (object);
 
-  g_object_unref (self->context);
-
   if (self->destroy)
-    self->destroy (self->data);
+    {
+      self->destroy (self->data);
+      self->destroy = NULL;
+      self->data = NULL;
+    }
+
+  g_clear_object (&self->context);
+  self->id = 0;
+
+  if (self->saved)
+    {
+      cairo_surface_destroy (self->saved);
+      self->saved = NULL;
+    }
 
   G_OBJECT_CLASS (gdk_gl_texture_parent_class)->dispose (object);
 }
@@ -474,7 +487,6 @@ gdk_gl_texture_download (GdkTexture *texture,
   GdkGLTexture *self = GDK_GL_TEXTURE (texture);
   cairo_surface_t *surface;
   cairo_t *cr;
-  GdkWindow *window;
 
   surface = cairo_image_surface_create_for_data (data,
                                                  CAIRO_FORMAT_ARGB32,
@@ -482,8 +494,21 @@ gdk_gl_texture_download (GdkTexture *texture,
                                                  stride);
 
   cr = cairo_create (surface);
-  window = gdk_gl_context_get_window (self->context);
-  gdk_cairo_draw_from_gl (cr, window, self->id, GL_TEXTURE, 1, 0, 0, texture->width, texture->height);
+
+  if (self->saved)
+    {
+      cairo_set_source_surface (cr, self->saved, 0, 0);
+      cairo_paint (cr);
+    }
+  else
+    {
+      GdkWindow *window;
+
+      window = gdk_gl_context_get_window (self->context);
+      gdk_cairo_draw_from_gl (cr, window, self->id, GL_TEXTURE, 1, 0, 0,
+                              texture->width, texture->height);
+    }
+
   cairo_destroy (cr);
   cairo_surface_finish (surface);
   cairo_surface_destroy (surface);
@@ -516,6 +541,41 @@ gdk_gl_texture_get_id (GdkGLTexture *self)
   return self->id;
 }
 
+void
+gdk_texture_release_gl (GdkTexture *texture)
+{
+  GdkGLTexture *self;
+  GdkWindow *window;
+  cairo_t *cr;
+
+  g_return_if_fail (GDK_IS_GL_TEXTURE (texture));
+
+  self = GDK_GL_TEXTURE (texture);
+
+  g_return_if_fail (self->saved == NULL);
+
+  self->saved = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+                                            texture->width, texture->height);
+
+  cr = cairo_create (self->saved);
+
+  window = gdk_gl_context_get_window (self->context);
+  gdk_cairo_draw_from_gl (cr, window, self->id, GL_TEXTURE, 1, 0, 0,
+                          texture->width, texture->height);
+
+  cairo_destroy (cr);
+
+  if (self->destroy)
+    {
+      self->destroy (self->data);
+      self->destroy = NULL;
+      self->data = NULL;
+    }
+
+  g_clear_object (&self->context);
+  self->id = 0;
+}
+
 /**
  * gdk_texture_new_for_pixbuf:
  * @pixbuf: a #GdkPixbuf
index 4f3ead2321245a5b88407955670d2008a28b9811..ae7ac812f2799f67e628f89881c21c9ff5b601d2 100644 (file)
@@ -64,6 +64,9 @@ GdkTexture *            gdk_texture_new_for_gl                 (GdkGLContext
                                                                 GDestroyNotify   destroy,
                                                                 gpointer         data);
 
+GDK_AVAILABLE_IN_3_94
+void                    gdk_texture_release_gl                 (GdkTexture      *texture);
+
 GDK_AVAILABLE_IN_3_94
 int                     gdk_texture_get_width                  (GdkTexture      *texture);
 GDK_AVAILABLE_IN_3_94